home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / programming / ixemul-complete / ixemul / glue / gen_glue.c next >
C/C++ Source or Header  |  1996-05-08  |  5KB  |  207 lines

  1. #include <sys/types.h>
  2. #include <sys/syscall.h>
  3.  
  4. #include <stdio.h>
  5.  
  6. struct syscall {
  7.   char *name;
  8.   int   vec;
  9. } syscalls[] = {
  10. #define SYSTEM_CALL(func,vec) { #func, vec},
  11. #include <sys/syscall.def>
  12. #undef SYSTEM_CALL
  13. };
  14.  
  15. int nsyscall = sizeof(syscalls) / sizeof (syscalls[0]);
  16.  
  17. #define IXEMULBASE "_ixemulbase"
  18. #define IXEMULBASELEN 11
  19.  
  20. #define BASEREL_OFFSET1 19
  21. #define BASEREL_OFFSET2 31
  22.  
  23. /* The following code is a hexdump of this assembly program:
  24.  
  25.         .globl    _FUNCTION
  26. _FUNCTION:    movel    a4@(_ixemulbase:W),a0
  27.         jmp    a0@(OFFSET:w)
  28. */
  29.  
  30. static short baserel_code[] = {
  31.   0x0000, 0x0107, 0x0000, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000,
  32.   0x0000, 0x0018, 0x0000, 0x0000, 0x0000, 0x0008, 0x0000, 0x0000,
  33.   0x206c, 0x0000, 0x4ee8, 0xff46, 0x0000, 0x0002, 0x0000, 0x0138,
  34.   0x0000, 0x0004, 0x0500, 0x0000, 0x0000, 0x0000, 0x0000, 0x0011,
  35.   0x0100, 0x0000, 0x0000, 0x0000
  36. };
  37.  
  38. #define NO_BASEREL_OFFSET1 20
  39. #define NO_BASEREL_OFFSET2 33
  40.  
  41. /* The following code is a hexdump of this assembly program:
  42.  
  43.         .globl    _FUNCTION
  44. _FUNCTION:    movel    _ixemulbase,a0
  45.         jmp    a0@(OFFSET:w)
  46. */
  47.  
  48. static short no_baserel_code[] = {
  49.   0x0000, 0x0107, 0x0000, 0x000c, 0x0000, 0x0000, 0x0000, 0x0000,
  50.   0x0000, 0x0018, 0x0000, 0x0000, 0x0000, 0x0008, 0x0000, 0x0000,
  51.   0x2079, 0x0000, 0x0000, 0x4ee8, 0xffe2, 0x0000, 0x0000, 0x0002,
  52.   0x0000, 0x0150, 0x0000, 0x0004, 0x0500, 0x0000, 0x0000, 0x0000,
  53.   0x0000, 0x000b, 0x0100, 0x0000, 0x0000, 0x0000
  54. };
  55.  
  56. #define PROFILING_OFFSET1 29
  57. #define PROFILING_OFFSET2 51
  58. #define PROFILING_OFFSET3 57
  59. #define PROFILING_OFFSET4 63
  60.  
  61. /* The following code is a hexdump of this assembly program:
  62.  
  63.         .globl    _FUNCTION
  64. _FUNCTION:
  65.         .data
  66. PROFFUNCTION:
  67.         .long    0
  68.  
  69.         .text
  70.         link    a5,#0
  71.         lea    PROFFUNCTION,a0
  72.         jsr    mcount
  73.         unlk    a5
  74.         movel    _ixemulbase,a0
  75.         jmp    a0@(OFFSET:w)
  76. */
  77.  
  78. static short profiling_code[] = {
  79.   0x0000, 0x0107, 0x0000, 0x001c, 0x0000, 0x0004, 0x0000, 0x0000,
  80.   0x0000, 0x0030, 0x0000, 0x0000, 0x0000, 0x0018, 0x0000, 0x0000,
  81.   0x4e55, 0x0000, 0x41f9, 0x0000, 0x001c, 0x4eb9, 0x0000, 0x0000,
  82.   0x4e5d, 0x2079, 0x0000, 0x0000, 0x4ee8, 0xffe2, 0x0000, 0x0000,
  83.   0x0000, 0x0006, 0x0000, 0x0640, 0x0000, 0x000c, 0x0000, 0x0250,
  84.   0x0000, 0x0014, 0x0000, 0x0350, 0x0000, 0x0004, 0x0500, 0x0000,
  85.   0x0000, 0x0000, 0x0000, 0x000b, 0x0600, 0x0000, 0x0000, 0x001c,
  86.   0x0000, 0x0015, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x001c,
  87.   0x0100, 0x0000, 0x0000, 0x0000
  88. };
  89.  
  90. void usage(void)
  91. {
  92.   fprintf(stderr, "Usage: gen_glue baserel | no-baserel | profiling\n");
  93.   exit(1);
  94. }
  95.  
  96. void write_code(short *code, int len, FILE *f)
  97. {
  98.   const short endian = 0x0100;
  99.  
  100.   /* test if gen_glue is compiled on a big or little endian machine */
  101.   if (((char *)&endian)[0])
  102.   {
  103.     fwrite(code, len, 1, f);        /* big endian */
  104.   }
  105.   else
  106.   {
  107.     int i;
  108.  
  109.     for (i = 0; i < len / 2; i++)
  110.     {
  111.       short x = code[i];        /* little endian */
  112.       
  113.       fputc(((char *)&x)[1], f);
  114.       fputc(((char *)&x)[0], f);
  115.     }
  116.   }
  117. }
  118.  
  119. int main(int argc, char **argv)
  120. {
  121.   FILE *fp;
  122.   struct syscall *sc;
  123.   int i, v, baserel = 0, profiling = 0;
  124.   short *code;
  125.   int offset1, offset2, size;
  126.   int zero = 0;
  127.  
  128.   if (argc != 2)
  129.     usage();
  130.   if (!strcmp(argv[1], "baserel"))
  131.     {
  132.       baserel = 1; profiling = 0;
  133.     }
  134.   else if (!strcmp(argv[1], "no-baserel"))
  135.     {
  136.       baserel = 0; profiling = 0;
  137.     }
  138.   else if (!strcmp(argv[1], "profiling"))
  139.     {
  140.       baserel = 0; profiling = 1;
  141.     }
  142.   else usage();
  143.   
  144.   for (i = 0, sc = syscalls; i < nsyscall; i++, sc++)
  145.     {
  146.       int namelen = strlen(sc->name);
  147.       char name[namelen + 3];
  148.  
  149.       if (!memcmp(sc->name, "__obsolete", 10))
  150.         continue;
  151.       if (!memcmp(sc->name, "__must_recompile", 16))
  152.         continue;
  153.       if (!memcmp(sc->name, "__stk", 5))
  154.         continue;
  155.       v = -(sc->vec + 4) * 6;
  156.       sprintf (name, "%s.o", sc->name);
  157.  
  158.       fp = fopen (name, "w");
  159.       
  160.       if (!fp)
  161.         {
  162.           perror (sc->name);
  163.           exit (20);
  164.         }
  165.  
  166.       code = no_baserel_code;
  167.       size = sizeof(no_baserel_code);
  168.       offset1 = NO_BASEREL_OFFSET1;
  169.       offset2 = NO_BASEREL_OFFSET2;
  170.       if (profiling)
  171.         {
  172.           profiling_code[PROFILING_OFFSET1] = v;
  173.           profiling_code[PROFILING_OFFSET2] = 6 + namelen;
  174.           profiling_code[PROFILING_OFFSET3] = 6 + namelen * 2 + 5;
  175.           profiling_code[PROFILING_OFFSET4] = 6 + namelen * 2 + 5 + 7;
  176.           write_code(profiling_code, sizeof(profiling_code), fp);
  177.           fwrite(&zero, 3, 1, fp);
  178.           fputc((char)(namelen * 2 + 7 + IXEMULBASELEN + 1 + 7 + 4), fp);
  179.           fputc('_', fp);
  180.           fwrite(sc->name, namelen + 1, 1, fp);
  181.           fprintf(fp, "PROF");
  182.           fwrite(sc->name, namelen + 1, 1, fp);
  183.           fwrite("mcount", 7, 1, fp);
  184.         }
  185.       else
  186.     {
  187.       if (baserel && sc->vec != SYS_ix_geta4)
  188.         {
  189.               code = baserel_code;
  190.               size = sizeof(baserel_code);
  191.               offset1 = BASEREL_OFFSET1;
  192.               offset2 = BASEREL_OFFSET2;
  193.             }
  194.           code[offset1] = v;
  195.           code[offset2] = namelen + 4 + 2;
  196.           write_code(code, size, fp);
  197.           fwrite(&zero, 3, 1, fp);
  198.           fputc((char)(namelen + 2 + IXEMULBASELEN + 1 + 4), fp);
  199.           fputc('_', fp);
  200.           fwrite(sc->name, namelen + 1, 1, fp);
  201.         }
  202.       fwrite(IXEMULBASE, IXEMULBASELEN + 1, 1, fp);
  203.       fclose (fp);
  204.     }
  205.   return (0);
  206. }
  207.